/*
 * Copyright (C) 2015  Hannes Hassler
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package rezeptsuperpos;

import java.awt.Desktop;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;

import org.jdom2.Element;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

/**
 *
 * @author hannes
 */
public class RecipeGUI extends javax.swing.JFrame {

    
    private static final long serialVersionUID = -2885954364097420292L;
	/**
     * Creates new form RecipeGUI
     */
    public IngredientArchive ingredientArchive = new IngredientArchive();
    public RecipeArchive recipeArchive = new RecipeArchive();
    Convert convert = new Convert();
    
	
    public RecipeGUI() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        ErrorOptionPane = new javax.swing.JOptionPane();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        ingredientPanel = new javax.swing.JPanel();
        nameTextField = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        aliasTextArea = new javax.swing.JTextArea();
        EnergyFatPanel = new javax.swing.JPanel();
        calTextField = new javax.swing.JTextField();
        carbTextField = new javax.swing.JTextField();
        fatTextField = new javax.swing.JTextField();
        protTextField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        calper_ml_Label = new javax.swing.JLabel();
        fatper_ml_Label = new javax.swing.JLabel();
        carb_per_ml_Label = new javax.swing.JLabel();
        prot_per_ml_Label = new javax.swing.JLabel();
        densityWeightPanel = new javax.swing.JPanel();
        densityTextField = new javax.swing.JTextField();
        weightPerPieceTextField = new javax.swing.JTextField();
        gPer_ml_Label = new javax.swing.JLabel();
        jLabel15 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel16 = new javax.swing.JLabel();
        ButtonPanel = new javax.swing.JPanel();
        volumeUnitComboBox = new javax.swing.JComboBox();
        prevButton = new javax.swing.JButton();
        nextButton = new javax.swing.JButton();
        searchIngredientFromNameButton = new javax.swing.JButton();
        newIngredientButton = new javax.swing.JButton();
        ingredientSaveButton = new javax.swing.JButton();
        deleteButton = new javax.swing.JButton();
        recipejPanel = new javax.swing.JPanel();
        recipeNameTextField = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        recipeSourceTextField = new javax.swing.JTextField();
        ingredientScrollPane2 = new javax.swing.JScrollPane();
        recipeIngredientsTable = new javax.swing.JTable();
        jLabel11 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        recipePreparationTextArea = new javax.swing.JTextArea();
        jLabel12 = new javax.swing.JLabel();
        recipePortionTextField = new javax.swing.JTextField();
        jLabel13 = new javax.swing.JLabel();
        moveUpButton = new javax.swing.JButton();
        moveDownButton = new javax.swing.JButton();
        cookNameTextField = new javax.swing.JTextField();
        jLabel14 = new javax.swing.JLabel();
        jPanel4 = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        recipePrevButton = new javax.swing.JButton();
        recipeNewButton = new javax.swing.JButton();
        recipeNextButton = new javax.swing.JButton();
        recipeSaveButton = new javax.swing.JButton();
        recipeSearchButton = new javax.swing.JButton();
        recipeDeleteButton = new javax.swing.JButton();
        recipeCheckButton = new javax.swing.JButton();
        recipeGramToggleButton = new javax.swing.JToggleButton();
        delIngredientButton = new javax.swing.JButton();
        getInfoButton = new javax.swing.JButton();
        ingredientInfoTextField = new javax.swing.JTextField();
        automaticWolframAlphaCheckBox = new javax.swing.JCheckBox();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        exitMenuItem = new javax.swing.JMenuItem();
        jMenu2 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTabbedPane1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        ingredientPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        nameTextField.setText("allspice");

        jLabel1.setText("Name");

        jLabel6.setText("Alias");

        jLabel2.setText("Unit");

        aliasTextArea.setColumns(20);
        aliasTextArea.setFont(new java.awt.Font("Monospaced", 0, 12));
        aliasTextArea.setRows(5);
        aliasTextArea.setText("Jamaica pepper, piment, \nnewspice, Neugewürz, \nNelkenpfeffer, Jamaikapfeffer, \nViergewürz, Allgewürz");
        aliasTextArea.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                aliasTextAreaKeyTyped(evt);
            }
        });
        jScrollPane1.setViewportView(aliasTextArea);

        calTextField.setText("0");

        carbTextField.setText("0");
        carbTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                carbTextFieldActionPerformed(evt);
            }
        });

        fatTextField.setText("0");

        protTextField.setText("0");

        jLabel4.setText("Energy");

        jLabel9.setText("Fat");

        jLabel5.setText("Carbohydrate");

        jLabel10.setText("Protein");

        calper_ml_Label.setText("cal/ml");

        fatper_ml_Label.setText("fat/ml");

        carb_per_ml_Label.setText("carb/ml");

        prot_per_ml_Label.setText("prot/ml");

        javax.swing.GroupLayout EnergyFatPanelLayout = new javax.swing.GroupLayout(EnergyFatPanel);
        EnergyFatPanel.setLayout(EnergyFatPanelLayout);
        EnergyFatPanelLayout.setHorizontalGroup(
            EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(EnergyFatPanelLayout.createSequentialGroup()
                .addGap(12, 12, 12)
                .addGroup(EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel9)
                    .addComponent(jLabel4)
                    .addComponent(jLabel5)
                    .addComponent(jLabel10))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(protTextField)
                    .addComponent(fatTextField)
                    .addComponent(carbTextField)
                    .addComponent(calTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(prot_per_ml_Label)
                    .addComponent(fatper_ml_Label)
                    .addComponent(calper_ml_Label)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, EnergyFatPanelLayout.createSequentialGroup()
                        .addComponent(carb_per_ml_Label, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(11, 11, 11)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        EnergyFatPanelLayout.setVerticalGroup(
            EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(EnergyFatPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(calTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(calper_ml_Label)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(carbTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(fatper_ml_Label, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(fatTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(carb_per_ml_Label)
                    .addComponent(jLabel5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(EnergyFatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(protTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(prot_per_ml_Label)
                    .addComponent(jLabel10))
                .addContainerGap(28, Short.MAX_VALUE))
        );

        densityTextField.setText("0.42");

        weightPerPieceTextField.setText("0.0");
        weightPerPieceTextField.setToolTipText("enter if applicable");

        gPer_ml_Label.setText("g/ml");

        jLabel15.setText("weight per piece");
        jLabel15.setToolTipText("if applicable");

        jLabel3.setText("Density");

        jLabel16.setText("g");

        javax.swing.GroupLayout densityWeightPanelLayout = new javax.swing.GroupLayout(densityWeightPanel);
        densityWeightPanel.setLayout(densityWeightPanelLayout);
        densityWeightPanelLayout.setHorizontalGroup(
            densityWeightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(densityWeightPanelLayout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(densityTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(gPer_ml_Label)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 47, Short.MAX_VALUE)
                .addComponent(jLabel15)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(weightPerPieceTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel16)
                .addGap(85, 85, 85))
        );
        densityWeightPanelLayout.setVerticalGroup(
            densityWeightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(densityWeightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(densityTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(weightPerPieceTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(gPer_ml_Label)
                .addComponent(jLabel15)
                .addComponent(jLabel3)
                .addComponent(jLabel16))
        );

        volumeUnitComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "ml", "g", "dag", "kg", "dl", "l", "t", "T", "floz", "oz", "cup", "pt", "qt", "gal", "lb" }));
        volumeUnitComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                volumeUnitComboBoxActionPerformed(evt);
            }
        });

        prevButton.setText("prev");
        prevButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                prevButtonActionPerformed(evt);
            }
        });

        nextButton.setText("next");
        nextButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextButtonActionPerformed(evt);
            }
        });

        searchIngredientFromNameButton.setText("search");
        searchIngredientFromNameButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchIngredientFromNameButtonActionPerformed(evt);
            }
        });

        newIngredientButton.setText("new");
        newIngredientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newIngredientButtonActionPerformed(evt);
            }
        });

        ingredientSaveButton.setText("save");
        ingredientSaveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ingredientSaveButtonActionPerformed(evt);
            }
        });

        deleteButton.setText("delete");
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout ButtonPanelLayout = new javax.swing.GroupLayout(ButtonPanel);
        ButtonPanel.setLayout(ButtonPanelLayout);
        ButtonPanelLayout.setHorizontalGroup(
            ButtonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ButtonPanelLayout.createSequentialGroup()
                .addComponent(volumeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(39, 39, 39)
                .addComponent(prevButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(nextButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(searchIngredientFromNameButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(newIngredientButton, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ingredientSaveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(68, Short.MAX_VALUE))
        );
        ButtonPanelLayout.setVerticalGroup(
            ButtonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ButtonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(volumeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(prevButton)
                .addComponent(nextButton)
                .addComponent(searchIngredientFromNameButton)
                .addComponent(newIngredientButton)
                .addComponent(ingredientSaveButton)
                .addComponent(deleteButton))
        );

        javax.swing.GroupLayout ingredientPanelLayout = new javax.swing.GroupLayout(ingredientPanel);
        ingredientPanel.setLayout(ingredientPanelLayout);
        ingredientPanelLayout.setHorizontalGroup(
            ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ingredientPanelLayout.createSequentialGroup()
                .addGap(10, 10, 10)
                .addGroup(ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel6)
                    .addGroup(ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(ingredientPanelLayout.createSequentialGroup()
                            .addGap(18, 18, 18)
                            .addComponent(jLabel2))
                        .addComponent(jLabel1)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(EnergyFatPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(densityWeightPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(ButtonPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(nameTextField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 516, Short.MAX_VALUE)))
                .addContainerGap())
        );
        ingredientPanelLayout.setVerticalGroup(
            ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ingredientPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(ingredientPanelLayout.createSequentialGroup()
                        .addComponent(ButtonPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(5, 5, 5)
                        .addGroup(ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel1)))
                    .addComponent(jLabel2))
                .addGap(11, 11, 11)
                .addGroup(ingredientPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel6)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(densityWeightPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(EnergyFatPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(344, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("Ingredient", ingredientPanel);

        recipejPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

        recipeNameTextField.setText(" ");

        jLabel7.setText("Name");

        jLabel8.setText("Quelle");

        recipeSourceTextField.setText(" ");

        recipeIngredientsTable.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        recipeIngredientsTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null}
            },
            new String [] {
                "Menge", "Einheit", "Zutat"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Float.class, java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        recipeIngredientsTable.setShowHorizontalLines(false);
        recipeIngredientsTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                recipeIngredientsTableMouseClicked(evt);
            }
        });
        recipeIngredientsTable.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                recipeIngredientsTableFocusGained(evt);
            }
        });
        recipeIngredientsTable.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                recipeIngredientsTableKeyTyped(evt);
            }
        });
        ingredientScrollPane2.setViewportView(recipeIngredientsTable);
        recipeIngredientsTable.getColumnModel().getColumn(0).setMinWidth(80);
        recipeIngredientsTable.getColumnModel().getColumn(0).setPreferredWidth(10);
        recipeIngredientsTable.getColumnModel().getColumn(0).setMaxWidth(150);
        recipeIngredientsTable.getColumnModel().getColumn(1).setMinWidth(80);
        recipeIngredientsTable.getColumnModel().getColumn(1).setPreferredWidth(10);
        recipeIngredientsTable.getColumnModel().getColumn(1).setMaxWidth(150);

        jLabel11.setText("Zutaten");

        recipePreparationTextArea.setColumns(20);
        recipePreparationTextArea.setRows(5);
        jScrollPane3.setViewportView(recipePreparationTextArea);

        jLabel12.setText("Zubereitung");

        recipePortionTextField.setText("4");

        jLabel13.setText("Portionen");

        moveUpButton.setText("move Up");
        moveUpButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                moveUpButtonActionPerformed(evt);
            }
        });

        moveDownButton.setText("move Dn");
        moveDownButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                moveDownButtonActionPerformed(evt);
            }
        });

        cookNameTextField.setText("Joe Cook");

        jLabel14.setText("Author");

        jPanel4.setLayout(new java.awt.BorderLayout());

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        recipePrevButton.setText("prev");
        recipePrevButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipePrevButtonActionPerformed(evt);
            }
        });

        recipeNewButton.setText("new");
        recipeNewButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipeNewButtonActionPerformed(evt);
            }
        });

        recipeNextButton.setText("next");
        recipeNextButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipeNextButtonActionPerformed(evt);
            }
        });

        recipeSaveButton.setText("save");
        recipeSaveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipeSaveButtonActionPerformed(evt);
            }
        });

        recipeSearchButton.setText("search");
        recipeSearchButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipeSearchButtonActionPerformed(evt);
            }
        });

        recipeDeleteButton.setText("delete");
        recipeDeleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipeDeleteButtonActionPerformed(evt);
            }
        });

        recipeCheckButton.setText("check");
        recipeCheckButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipeCheckButtonActionPerformed(evt);
            }
        });

        recipeGramToggleButton.setText("showInGram");
        recipeGramToggleButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recipeGramToggleButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(recipeGramToggleButton, javax.swing.GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE)
            .addComponent(recipeCheckButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(recipePrevButton, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE)
                    .addComponent(recipeNextButton, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE)
                    .addComponent(recipeSearchButton, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE))
                .addGap(12, 12, 12)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(recipeSaveButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(recipeNewButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(recipeDeleteButton, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE)))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(recipePrevButton)
                    .addComponent(recipeNewButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(recipeNextButton)
                    .addComponent(recipeSaveButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(recipeSearchButton)
                    .addComponent(recipeDeleteButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(recipeCheckButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(recipeGramToggleButton)
                .addGap(0, 17, Short.MAX_VALUE))
        );

        delIngredientButton.setText("del Ingr");
        delIngredientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                delIngredientButtonActionPerformed(evt);
            }
        });

        getInfoButton.setText("get Info for");
        getInfoButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getInfoButtonActionPerformed(evt);
            }
        });

        ingredientInfoTextField.setText("lentils");

        automaticWolframAlphaCheckBox.setSelected(true);
        automaticWolframAlphaCheckBox.setText("open Wolfram Alpha for unkown ingredients automatically");
        automaticWolframAlphaCheckBox.setToolTipText("you need Internet connection and a browser on your PC to use that option");

        javax.swing.GroupLayout recipejPanelLayout = new javax.swing.GroupLayout(recipejPanel);
        recipejPanel.setLayout(recipejPanelLayout);
        recipejPanelLayout.setHorizontalGroup(
            recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(recipejPanelLayout.createSequentialGroup()
                .addGap(10, 10, 10)
                .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel8)
                    .addComponent(jLabel13)
                    .addComponent(jLabel7)
                    .addComponent(jLabel12)
                    .addComponent(moveUpButton)
                    .addComponent(jLabel11)
                    .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(delIngredientButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(moveDownButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(recipejPanelLayout.createSequentialGroup()
                        .addComponent(automaticWolframAlphaCheckBox)
                        .addContainerGap())
                    .addGroup(recipejPanelLayout.createSequentialGroup()
                        .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 544, Short.MAX_VALUE)
                            .addGroup(recipejPanelLayout.createSequentialGroup()
                                .addComponent(recipePortionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(4, 4, 4)
                                .addComponent(jLabel14)
                                .addGap(4, 4, 4)
                                .addComponent(cookNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(recipejPanelLayout.createSequentialGroup()
                                .addComponent(ingredientScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 382, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(getInfoButton)
                                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(ingredientInfoTextField)))
                            .addComponent(recipeSourceTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 544, Short.MAX_VALUE)
                            .addComponent(recipeNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 544, Short.MAX_VALUE))
                        .addGap(18, 18, 18)
                        .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(632, 632, 632))))
        );
        recipejPanelLayout.setVerticalGroup(
            recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(recipejPanelLayout.createSequentialGroup()
                .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(recipejPanelLayout.createSequentialGroup()
                        .addGap(30, 30, 30)
                        .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(recipeNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel7))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(recipeSourceTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel8))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(recipePortionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel13)
                            .addComponent(cookNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel14)))
                    .addGroup(recipejPanelLayout.createSequentialGroup()
                        .addGap(48, 48, 48)
                        .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(9, 9, 9)
                .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(recipejPanelLayout.createSequentialGroup()
                        .addComponent(jLabel11)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(moveUpButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(moveDownButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(delIngredientButton))
                    .addComponent(ingredientScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(recipejPanelLayout.createSequentialGroup()
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(getInfoButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(ingredientInfoTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(automaticWolframAlphaCheckBox)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 37, Short.MAX_VALUE)
                .addGroup(recipejPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel12)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(121, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("Recipe", recipejPanel);

        try {
            switch2Unit("g");
            set2Ingredient(ingredientArchive.getFirst());
            set2Recipe(recipeArchive.getFirst());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        jMenu1.setText("File");

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(exitMenuItem);

        jMenuBar1.add(jMenu1);

        jMenu2.setText("About");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 655, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 722, Short.MAX_VALUE)
                .addGap(22, 22, 22))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void ingredientSaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ingredientSaveButtonActionPerformed
    	
    	Element curIngElem=ingredientArchive.getCurrentElement();
        String currentUnitName="g";
        try {
           currentUnitName=this.getUnitNameFromLabel(this.calper_ml_Label.getText());
        } catch (Exception ex) {
            //ignore
        }
        try {
            this.switch2Unit("g");
        
        if (curIngElem==null) {
            Element ingredientElement = new Element("ingredient");                
            ingredientElement.addContent(createElement("name",this.nameTextField.getText().trim()));
            ingredientElement.addContent(createElement("alias",this.aliasTextArea.getText()));
            ingredientElement.addContent(createElement("density",this.densityTextField.getText()));
            ingredientElement.addContent(createElement("calSpec",this.calTextField.getText()));
            ingredientElement.addContent(createElement("carbSpec",this.carbTextField.getText()));
            ingredientElement.addContent(createElement("fatSpec",this.fatTextField.getText()));
            ingredientElement.addContent(createElement("protSpec",this.protTextField.getText()));               
            try {
				ingredientArchive.insertIngredient(ingredientElement);
				curIngElem=ingredientArchive.getCurrentElement();
			} catch (FileNotFoundException e) {				
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {				
				e.printStackTrace();
			}
        }      
        this.repaint();
    	curIngElem.getChild("name").setText(this.nameTextField.getText().trim());
    	MyElement.setChild(curIngElem, "alias", this.aliasTextArea.getText());    	
    	MyElement.setChild(curIngElem,"density",this.densityTextField.getText());
    	MyElement.setChild(curIngElem,"calSpec",calTextField.getText());
    	MyElement.setChild(curIngElem,"fatSpec",fatTextField.getText());
    	MyElement.setChild(curIngElem,"protSpec",protTextField.getText());
    	MyElement.setChild(curIngElem,"carbSpec",carbTextField.getText());  
        MyElement.setChild(curIngElem,"weightPerPiece",this.weightPerPieceTextField.getText());        
    	try {
			ingredientArchive.saveIngredients();
		} catch (FileNotFoundException e) {			
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {			
			e.printStackTrace();
		}
        try {
            switch2Unit(currentUnitName);
        }   catch (Exception ex) {
            ex.printStackTrace();
        } 
        } catch (Exception ex) {
          ex.printStackTrace();
          this.ErrorOptionPane.showMessageDialog(this,ExceptionMessage.densityIsNull);   
        }
        
    }//GEN-LAST:event_ingredientSaveButtonActionPerformed

    private String formatAliasText(String unformattedText) {
        unformattedText=unformattedText.replaceAll("\n", "");
        StringBuilder retVal = new StringBuilder();
        
        int posCount=0;
        for (int strIdx=0;strIdx<unformattedText.length()-1;strIdx++) {            
            String currChar=unformattedText.substring(strIdx, strIdx+1);
            retVal.append(currChar);
            posCount++;
            if (currChar.equalsIgnoreCase(",") && posCount>20) {
                retVal.append("\n");
                posCount=0;
            }            
        }
        if (unformattedText.length()>0) retVal.append(unformattedText.substring(unformattedText.length()-1));
        return retVal.toString().replaceAll("\n ", "\n");
    }
    
    private Element createElement(String name, String val) {
        return MyElement.createElement(name, val);
    }
    private void volumeUnitComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_volumeUnitComboBoxActionPerformed
        String unit=this.volumeUnitComboBox.getSelectedItem().toString();
        try {
            switch2Unit(unit);
        } catch (Exception ex) {
            if (ex.getMessage().equalsIgnoreCase(ExceptionMessage.densityIsNull)) {
                ErrorOptionPane.showMessageDialog(this,ExceptionMessage.densityIsNull);
                volumeUnitComboBox.setSelectedItem(getUnitNameFromLabel(calper_ml_Label.getText()));
            }
        }
    }//GEN-LAST:event_volumeUnitComboBoxActionPerformed

    private void switch2Unit(String newUnit) throws Exception {
        String densityContent=this.densityTextField.getText();
        double  density = Double.parseDouble(densityContent);
        convertUnit("cal",calper_ml_Label,calTextField, newUnit,density);
        convertUnit("carb",carb_per_ml_Label,carbTextField, newUnit,density);
        convertUnit("fat",fatper_ml_Label,fatTextField, newUnit,density);
        convertUnit("prot",prot_per_ml_Label,protTextField, newUnit,density);        
    }
    
    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        System.exit(0);
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextButtonActionPerformed
        if (ingredientArchive.currElementOfDocument<ingredientArchive.size()-1) {
            ingredientArchive.currElementOfDocument++;
            set2Ingredient(new Ingredient(ingredientArchive.getCurrentElement()));
        }
    }//GEN-LAST:event_nextButtonActionPerformed

    private void aliasTextAreaKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_aliasTextAreaKeyTyped
        
    }//GEN-LAST:event_aliasTextAreaKeyTyped

    private void newIngredientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newIngredientButtonActionPerformed
        Ingredient ingredient = new Ingredient("ingredient");        
        try {
            this.ingredientArchive.insertIngredient(ingredient);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        set2Ingredient(ingredient);
    }//GEN-LAST:event_newIngredientButtonActionPerformed

    private void prevButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevButtonActionPerformed
        if (ingredientArchive.currElementOfDocument>0) {
            ingredientArchive.currElementOfDocument--;
            set2Ingredient(new Ingredient(ingredientArchive.getCurrentElement()));
        }
    }//GEN-LAST:event_prevButtonActionPerformed

    private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
        ingredientArchive.deleteCurrentIngredient();
        set2Ingredient(ingredientArchive.getFirst());
        try {
            ingredientArchive.saveIngredients();
        } catch (Exception ex) {
            ErrorOptionPane.showMessageDialog(this,ex.getMessage());
        }
    }//GEN-LAST:event_deleteButtonActionPerformed

    private void searchIngredientFromNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchIngredientFromNameButtonActionPerformed
        set2Ingredient(ingredientArchive.searchIngredient(this.nameTextField.getText()));
    }//GEN-LAST:event_searchIngredientFromNameButtonActionPerformed

    private void recipeCheckButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipeCheckButtonActionPerformed
        DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel();
        boolean finished=false;
        for (int rowIdx=0;rowIdx<dtm.getRowCount();rowIdx++) {
            for (int colIdx=0; colIdx<dtm.getColumnCount(); colIdx++)
            if (dtm.getValueAt(rowIdx, colIdx)!=null) {
                System.out.print("\t"+dtm.getValueAt(rowIdx, colIdx));
            } else
            finished=true;
            if (!finished) System.out.println("\n");
        }
    }//GEN-LAST:event_recipeCheckButtonActionPerformed

    private void recipeSearchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipeSearchButtonActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_recipeSearchButtonActionPerformed

    private void recipeSaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipeSaveButtonActionPerformed
        saveRecipe();
    }//GEN-LAST:event_recipeSaveButtonActionPerformed

    private void saveRecipe() {
        Element curRecipeElem=recipeArchive.getCurrentElement();

        if (curRecipeElem!=null && !recipeGramToggleButton.isSelected()) {            
            curRecipeElem.getChild("name").setText(this.recipeNameTextField.getText());
            
            curRecipeElem.getChild("ingredients").removeChildren("ingredient");
            DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel();
            boolean canBeSaved=true;
            for (int rowIdx=0;rowIdx<dtm.getRowCount()&&dtm.getValueAt(rowIdx, 0)!=null;rowIdx++) {
                double measure=Double.parseDouble(dtm.getValueAt(rowIdx, 0).toString());
                String unit=dtm.getValueAt(rowIdx, 1).toString();
                String name=dtm.getValueAt(rowIdx, 2).toString();
                Ingredient ingredient;
                Ingredient genericIngredient = this.ingredientArchive.searchIngredient(name);
                if (genericIngredient!=null && genericIngredient.density>0) {
                    ingredient = new Ingredient(
                        measure,
                        unit,
                        name,
                        genericIngredient                        
                    );
                    curRecipeElem.getChild("ingredients").addContent(ingredient.toElement());
                    MyElement.setChild(curRecipeElem, "source",this.recipeSourceTextField.getText());
                    MyElement.setChild(curRecipeElem, "preparation", this.recipePreparationTextArea.getText());
                    MyElement.setChild(curRecipeElem, "portions", this.recipePortionTextField.getText());
                    MyElement.setChild(curRecipeElem, "cook", this.cookNameTextField.getText());
                } else {
                    canBeSaved=false; 
                    if (genericIngredient==null) {                        
                        IngredientDialog ingredientDialog = new IngredientDialog(this, true);
                        ingredientDialog.setTitle("New Ingredient");
                        String nameRump=IngredientArchive.nameRump(name);
                        if (this.automaticWolframAlphaCheckBox.isSelected())
                            openWolframInfo(nameRump);
                        this.ingredientInfoTextField.setText(nameRump);
                        ingredientDialog.ingredientNameTextField.setText(nameRump);
                        ingredientDialog.show();
                    }
                    else {
                        if (genericIngredient.density<=0)
                        this.ErrorOptionPane.showMessageDialog(this,ExceptionMessage.densityIsNull+":"+name);
                    }
                }

            }
            try {
                if (canBeSaved) recipeArchive.saveRecipes();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    private void recipeNextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipeNextButtonActionPerformed
        if (this.recipeArchive.currElementOfDocument<recipeArchive.size()-1)
        recipeArchive.currElementOfDocument++;
        set2Recipe(recipeArchive.getCurrentRecipe());
    }//GEN-LAST:event_recipeNextButtonActionPerformed

    private void recipeNewButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipeNewButtonActionPerformed
        Recipe recipe = new Recipe("recipe");
        try {
            this.recipeArchive.insertRecipe(recipe);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        set2Recipe(recipe);
    }//GEN-LAST:event_recipeNewButtonActionPerformed

    private void recipePrevButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipePrevButtonActionPerformed
        if (this.recipeArchive.currElementOfDocument>0)
        recipeArchive.currElementOfDocument--;
        set2Recipe(recipeArchive.getCurrentRecipe());
    }//GEN-LAST:event_recipePrevButtonActionPerformed

    private void moveDownButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveDownButtonActionPerformed
        DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel();
        if (this.recipeIngredientsTable.getSelectedRow()<this.recipeIngredientsTable.getRowCount()) {
            int upperRow=recipeIngredientsTable.getSelectedRow()+1;
            int thisRow=recipeIngredientsTable.getSelectedRow();
            double upperRowAmount=Double.parseDouble(dtm.getValueAt(upperRow, 0).toString());
            String upperRowUnit=dtm.getValueAt(upperRow, 1).toString();
            String upperRowName=dtm.getValueAt(upperRow, 2).toString();
            dtm.setValueAt(dtm.getValueAt(thisRow,0), upperRow, 0);
            dtm.setValueAt(dtm.getValueAt(thisRow,1), upperRow, 1);
            dtm.setValueAt(dtm.getValueAt(thisRow,2), upperRow, 2);
            dtm.setValueAt(upperRowAmount, thisRow, 0);
            dtm.setValueAt(upperRowUnit, thisRow, 1);
            dtm.setValueAt(upperRowName, thisRow, 2);
            this.recipeIngredientsTable.setRowSelectionInterval(upperRow, upperRow);
        }
    }//GEN-LAST:event_moveDownButtonActionPerformed

    private void moveUpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveUpButtonActionPerformed
        DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel();
        if (this.recipeIngredientsTable.getSelectedRow()>0) {
            int upperRow=recipeIngredientsTable.getSelectedRow()-1;
            int thisRow=recipeIngredientsTable.getSelectedRow();
            double upperRowAmount=Double.parseDouble(dtm.getValueAt(upperRow, 0).toString());
            String upperRowUnit=dtm.getValueAt(upperRow, 1).toString();
            String upperRowName=dtm.getValueAt(upperRow, 2).toString();
            dtm.setValueAt(dtm.getValueAt(thisRow,0), upperRow, 0);
            dtm.setValueAt(dtm.getValueAt(thisRow,1), upperRow, 1);
            dtm.setValueAt(dtm.getValueAt(thisRow,2), upperRow, 2);
            dtm.setValueAt(upperRowAmount, thisRow, 0);
            dtm.setValueAt(upperRowUnit, thisRow, 1);
            dtm.setValueAt(upperRowName, thisRow, 2);
            this.recipeIngredientsTable.setRowSelectionInterval(upperRow, upperRow);
        }
    }//GEN-LAST:event_moveUpButtonActionPerformed

    private void recipeIngredientsTableKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_recipeIngredientsTableKeyTyped
        //System.out.println("Key pressed:"+((int)evt.getKeyChar()));
        DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel();
        if ((int)evt.getKeyChar()==9 && this.recipeIngredientsTable.getSelectedColumn()==0) {
           saveRecipe(); 
        };
    }//GEN-LAST:event_recipeIngredientsTableKeyTyped

    private void recipeGramToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipeGramToggleButtonActionPerformed
        Recipe recipe=recipeArchive.getCurrentRecipe();
        DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel(); 
        clearIngredientsTable();                              
            for (int ingredIdx=0; ingredIdx<recipe.ingredients.size();ingredIdx++) {
                    Ingredient ingredient = recipe.ingredients.get(ingredIdx);
                    if (this.recipeGramToggleButton.isSelected()) {  
                        dtm.setValueAt(ingredient.measureInGram, ingredIdx,0);
                        dtm.setValueAt("g", ingredIdx,1);                                        
                    } else {
                        dtm.setValueAt(ingredient.measure, ingredIdx,0);
                        dtm.setValueAt(ingredient.measureUnit, ingredIdx,1);
                    }
                    dtm.setValueAt(ingredient.name, ingredIdx,2);
            }
        
        
    }//GEN-LAST:event_recipeGramToggleButtonActionPerformed

    private void delIngredientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delIngredientButtonActionPerformed
        int currentIngredient=this.recipeIngredientsTable.getSelectedRow();
        Element recipe=recipeArchive.getCurrentElement();        
        int ingredIdx=0; 
        Element reducedIngredients=MyElement.createElement("ingredients", "");        
        for (Element element: recipe.getChild("ingredients").getChildren()) {
            if (ingredIdx!=currentIngredient) {                
                Ingredient ingredient = new Ingredient(element);
                reducedIngredients.addContent(ingredient.toElement());                
            }
            ingredIdx++;
        };
        recipe.removeChild("ingredients");
        recipe.addContent(reducedIngredients);
        try {
            recipeArchive.saveRecipes();
        } catch (Exception ex) {                        
            this.ErrorOptionPane.showMessageDialog(this,ExceptionMessage.couldnotSave);
        }
        set2Recipe(recipeArchive.getCurrentRecipe());
    }//GEN-LAST:event_delIngredientButtonActionPerformed

    private void recipeDeleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recipeDeleteButtonActionPerformed
        try {
            this.recipeArchive.deleteRecipe(recipeArchive.currElementOfDocument);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        set2Recipe(recipeArchive.getCurrentRecipe());          
    }//GEN-LAST:event_recipeDeleteButtonActionPerformed

    private void carbTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_carbTextFieldActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_carbTextFieldActionPerformed

    private void recipeIngredientsTableFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_recipeIngredientsTableFocusGained
        //recipeIngredientsTable.editCellAt(recipeIngredientsTable.getSelectedRow(),recipeIngredientsTable.getSelectedColumn());
    }//GEN-LAST:event_recipeIngredientsTableFocusGained

    private void getInfoButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_getInfoButtonActionPerformed
        openWolframInfo(this.ingredientInfoTextField.getText().trim());
    }//GEN-LAST:event_getInfoButtonActionPerformed

    private void recipeIngredientsTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_recipeIngredientsTableMouseClicked
       
       System.out.println("Table mouse clicked");
        //DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel();
       /*
       String currValue=dtm.getValueAt(recipeIngredientsTable.getSelectedRow(), recipeIngredientsTable.getSelectedColumn()).toString();
       dtm.setValueAt("", recipeIngredientsTable.getSelectedRow(), recipeIngredientsTable.getSelectedColumn());
       dtm.setValueAt(currValue, recipeIngredientsTable.getSelectedRow(), recipeIngredientsTable.getSelectedColumn());
       */
       //recipeIngredientsTable.selectAll();
       //TableCellEditor cellEditor = recipeIngredientsTable.getCellEditor(recipeIngredientsTable.getSelectedRow(), recipeIngredientsTable.getSelectedColumn());
       //cellEditor.get
    }//GEN-LAST:event_recipeIngredientsTableMouseClicked

    private void openWolframInfo(String ingredientName) {
        URI uri=null;
		try {
			uri = new URI("http://www.wolframalpha.com/input/?i="+ingredientName.replaceAll(" ", "+"));
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        open(uri);
    }
    
    private static void open(URI uri) {
    if (Desktop.isDesktopSupported()) {
      try {
        Desktop.getDesktop().browse(uri);
      } catch (IOException e) { /* TODO: error handling */ }
    } else { /* TODO: error handling */ }
    }
    
    private String element2String(Element element) {
        Format format=Format.getPrettyFormat();
                XMLOutputter xmlOutputter = new XMLOutputter();
                xmlOutputter.setFormat(format);
        return xmlOutputter.outputString(element); 
    }
    
    private void clearIngredientsTable() {
        DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel();
        for (int rowIdx=0; rowIdx<dtm.getRowCount();rowIdx++) {
              dtm.setValueAt(null, rowIdx, 0);
              dtm.setValueAt("", rowIdx, 1);
              dtm.setValueAt("", rowIdx, 2);            
        }
    }
    private void set2Recipe(Recipe recipe) {
           if (recipe!=null) {
            this.recipeNameTextField.setText(recipe.name);
            this.recipeSourceTextField.setText(recipe.source);
            DefaultTableModel dtm = (DefaultTableModel) recipeIngredientsTable.getModel(); 
            clearIngredientsTable();
            for (int ingredIdx=0; ingredIdx<recipe.ingredients.size();ingredIdx++) {
                    Ingredient ingredient = recipe.ingredients.get(ingredIdx);
                    dtm.setValueAt(ingredient.measure, ingredIdx,0);
                    dtm.setValueAt(ingredient.measureUnit, ingredIdx,1);
                    dtm.setValueAt(ingredient.name, ingredIdx,2);                
            }
            this.recipePreparationTextArea.setText(recipe.preparation);
            this.recipePortionTextField.setText(""+recipe.portions);
            this.cookNameTextField.setText(recipe.cook);
           }
    }
    
    private void set2Ingredient(Ingredient ingredient) {
        if (ingredient!=null) {
            this.nameTextField.setText(ingredient.name);
            this.aliasTextArea.setText(formatAliasText(ingredient.aliasCSV()));
            this.densityTextField.setText(""+ingredient.density);
            this.calTextField.setText(""+ingredient.calSpec);
            this.carbTextField.setText(""+ingredient.carbSpec);
            this.fatTextField.setText(""+ingredient.fatSpec);
            this.protTextField.setText(""+ingredient.protSpec);
            this.weightPerPieceTextField.setText(""+ingredient.weightPerPiece);
        } else {
            this.nameTextField.setText("allspice");
            this.aliasTextArea.setText("Jamaica pepper, piment, newspice, \n"
                    + "Neugewürz, Nelkenpfeffer, Jamaikapfeffer,\n"
                    + "Viergewürz, Allgewürz");
            this.densityTextField.setText("0.42");
            this.calTextField.setText("0.0");
            this.carbTextField.setText("0.0");
            this.fatTextField.setText("0.0");
            this.protTextField.setText("0.0");
        }
    }
    
    private String getUnitNameFromLabel(String labelText) {
        return labelText.substring(labelText.indexOf("/")+1);        
    }
    
    private void convertUnit(String labelPrefix, javax.swing.JLabel unitLabel, javax.swing.JTextField unitTextField, String newUnit, double density) 
    throws Exception {
       String oldUnit=getUnitNameFromLabel(unitLabel.getText());              
       double fieldVal=0;
       try {fieldVal=Double.parseDouble(unitTextField.getText().trim());} catch (Exception ex) {/*ignore, set to 0*/}
       double fieldValNew=convert.units(oldUnit, newUnit, fieldVal, density, nameTextField.getName());
       unitTextField.setText(""+fieldValNew);
       unitLabel.setText(labelPrefix+"/"+newUnit);       
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(RecipeGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(RecipeGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(RecipeGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(RecipeGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new RecipeGUI().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel ButtonPanel;
    private javax.swing.JPanel EnergyFatPanel;
    private javax.swing.JOptionPane ErrorOptionPane;
    private javax.swing.JTextArea aliasTextArea;
    private javax.swing.JCheckBox automaticWolframAlphaCheckBox;
    private javax.swing.JTextField calTextField;
    private javax.swing.JLabel calper_ml_Label;
    private javax.swing.JTextField carbTextField;
    private javax.swing.JLabel carb_per_ml_Label;
    private javax.swing.JTextField cookNameTextField;
    private javax.swing.JButton delIngredientButton;
    private javax.swing.JButton deleteButton;
    private javax.swing.JTextField densityTextField;
    private javax.swing.JPanel densityWeightPanel;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JTextField fatTextField;
    private javax.swing.JLabel fatper_ml_Label;
    private javax.swing.JLabel gPer_ml_Label;
    private javax.swing.JButton getInfoButton;
    private javax.swing.JTextField ingredientInfoTextField;
    private javax.swing.JPanel ingredientPanel;
    private javax.swing.JButton ingredientSaveButton;
    private javax.swing.JScrollPane ingredientScrollPane2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JButton moveDownButton;
    private javax.swing.JButton moveUpButton;
    private javax.swing.JTextField nameTextField;
    private javax.swing.JButton newIngredientButton;
    private javax.swing.JButton nextButton;
    private javax.swing.JButton prevButton;
    private javax.swing.JTextField protTextField;
    private javax.swing.JLabel prot_per_ml_Label;
    private javax.swing.JButton recipeCheckButton;
    private javax.swing.JButton recipeDeleteButton;
    private javax.swing.JToggleButton recipeGramToggleButton;
    private javax.swing.JTable recipeIngredientsTable;
    private javax.swing.JTextField recipeNameTextField;
    private javax.swing.JButton recipeNewButton;
    private javax.swing.JButton recipeNextButton;
    private javax.swing.JTextField recipePortionTextField;
    private javax.swing.JTextArea recipePreparationTextArea;
    private javax.swing.JButton recipePrevButton;
    private javax.swing.JButton recipeSaveButton;
    private javax.swing.JButton recipeSearchButton;
    private javax.swing.JTextField recipeSourceTextField;
    private javax.swing.JPanel recipejPanel;
    private javax.swing.JButton searchIngredientFromNameButton;
    private javax.swing.JComboBox volumeUnitComboBox;
    private javax.swing.JTextField weightPerPieceTextField;
    // End of variables declaration//GEN-END:variables
}
